package com.example.qiniutest.aliyun.oss.util;


import lombok.extern.log4j.Log4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.math.BigInteger;

@Component
@ConfigurationProperties(prefix = "aliyun.encryption")
@Log4j
public class HexadecimalEncryption {

    /**
     * 加密算法相关
     */
    private String ALGORITHM;

    private String CIPHER_ALGORITHM;
    /**
     * 加密密钥 必须byte数组为8位
     */
    private String SECRET_KEY;

    /**
     * 加密
     * @param data 数据
     * @return 16进制字符串
     * @throws Exception
     */
    public String encryption(String data) throws Exception{
        // 创建密钥
        DESKeySpec desKeySpec = new DESKeySpec(SECRET_KEY.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        // 加密
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] bs = cipher.doFinal(data.getBytes("UTF-8"));
        // 编码成16进制字符串
        BigInteger bi = new BigInteger(1, bs);
        return bi.toString(16);
    }

    /**
     * 解密
     * @param hex
     * @return
     * @throws Exception
     */
    public String decryption(String hex) throws Exception {
        // 解码16进制字符串
        BigInteger bi = new BigInteger(hex, 16);
        // 该数组包含此 BigInteger 的二进制补码表示形式。
        byte[] bs = bi.toByteArray();
        byte[] originBs = new byte[bs.length - 1];
        byte[] target = bs;
        if (bs[0] == 0) {
            log.info("去补码...");
            // 去掉补码
            System.arraycopy(bs, 1, originBs, 0, originBs.length);
            target = originBs;
        }
        // 创建密钥
        DESKeySpec desKeySpec = new DESKeySpec(SECRET_KEY.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        // 解密
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptionBs = cipher.doFinal(target);
        return new String(decryptionBs, "UTF-8");
    }


    public String getALGORITHM() {
        return ALGORITHM;
    }

    public void setALGORITHM(String ALGORITHM) {
        this.ALGORITHM = ALGORITHM;
    }

    public String getCIPHER_ALGORITHM() {
        return CIPHER_ALGORITHM;
    }

    public void setCIPHER_ALGORITHM(String CIPHER_ALGORITHM) {
        this.CIPHER_ALGORITHM = CIPHER_ALGORITHM;
    }

    public String getSECRET_KEY() {
        return SECRET_KEY;
    }

    public void setSECRET_KEY(String SECRET_KEY) {
        this.SECRET_KEY = SECRET_KEY;
    }
}
